extern int svm_dbg_on;
-#define GUEST_SEGMENT_LIMIT 0xffffffff
-
#define IOPM_SIZE (12 * 1024)
#define MSRPM_SIZE (8 * 1024)
{
struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
struct vmcb_struct *vmcb = arch_svm->vmcb;
- svm_segment_attributes_t attrib;
/* TLB control, and ASID assigment. */
svm_asid_init_vcpu(v);
vmcb->efer = EFER_SVME;
/* Guest segment limits. */
- vmcb->cs.limit = GUEST_SEGMENT_LIMIT;
- vmcb->es.limit = GUEST_SEGMENT_LIMIT;
- vmcb->ss.limit = GUEST_SEGMENT_LIMIT;
- vmcb->ds.limit = GUEST_SEGMENT_LIMIT;
- vmcb->fs.limit = GUEST_SEGMENT_LIMIT;
- vmcb->gs.limit = GUEST_SEGMENT_LIMIT;
+ vmcb->cs.limit = ~0u;
+ vmcb->es.limit = ~0u;
+ vmcb->ss.limit = ~0u;
+ vmcb->ds.limit = ~0u;
+ vmcb->fs.limit = ~0u;
+ vmcb->gs.limit = ~0u;
/* Guest segment bases. */
vmcb->cs.base = 0;
vmcb->gs.base = 0;
/* Guest segment AR bytes. */
- attrib.bytes = 0;
- attrib.fields.type = 0x3; /* type = 3 */
- attrib.fields.s = 1; /* code or data, i.e. not system */
- attrib.fields.dpl = 0; /* DPL = 0 */
- attrib.fields.p = 1; /* segment present */
- attrib.fields.db = 1; /* 32-bit */
- attrib.fields.g = 1; /* 4K pages in limit */
- vmcb->es.attr = attrib;
- vmcb->ss.attr = attrib;
- vmcb->ds.attr = attrib;
- vmcb->fs.attr = attrib;
- vmcb->gs.attr = attrib;
- attrib.fields.type = 0xb; /* type=0xb -> executable/readable, accessed */
- vmcb->cs.attr = attrib;
+ vmcb->es.attr.bytes = 0xc93; /* read/write, accessed */
+ vmcb->ss.attr.bytes = 0xc93;
+ vmcb->ds.attr.bytes = 0xc93;
+ vmcb->fs.attr.bytes = 0xc93;
+ vmcb->gs.attr.bytes = 0xc93;
+ vmcb->cs.attr.bytes = 0xc9b; /* exec/read, accessed */
/* Guest IDT. */
vmcb->idtr.base = 0;
vmcb->ldtr.attr.bytes = 0;
/* Guest TSS. */
- attrib.fields.type = 0xb; /* 32-bit TSS (busy) */
- vmcb->tr.attr = attrib;
+ vmcb->tr.attr.bytes = 0x08b; /* 32-bit TSS (busy) */
vmcb->tr.base = 0;
vmcb->tr.limit = 0xff;
}
}
-#define GUEST_SEGMENT_LIMIT 0xffffffff
-
static int construct_vmcs(struct vcpu *v)
{
- union vmcs_arbytes arbytes;
uint16_t sysenter_cs;
unsigned long sysenter_eip;
__vmwrite(GUEST_CS_BASE, 0);
/* Guest segment limits. */
- __vmwrite(GUEST_ES_LIMIT, GUEST_SEGMENT_LIMIT);
- __vmwrite(GUEST_SS_LIMIT, GUEST_SEGMENT_LIMIT);
- __vmwrite(GUEST_DS_LIMIT, GUEST_SEGMENT_LIMIT);
- __vmwrite(GUEST_FS_LIMIT, GUEST_SEGMENT_LIMIT);
- __vmwrite(GUEST_GS_LIMIT, GUEST_SEGMENT_LIMIT);
- __vmwrite(GUEST_CS_LIMIT, GUEST_SEGMENT_LIMIT);
+ __vmwrite(GUEST_ES_LIMIT, ~0u);
+ __vmwrite(GUEST_SS_LIMIT, ~0u);
+ __vmwrite(GUEST_DS_LIMIT, ~0u);
+ __vmwrite(GUEST_FS_LIMIT, ~0u);
+ __vmwrite(GUEST_GS_LIMIT, ~0u);
+ __vmwrite(GUEST_CS_LIMIT, ~0u);
/* Guest segment AR bytes. */
- arbytes.bytes = 0;
- arbytes.fields.seg_type = 0x3; /* type = 3 */
- arbytes.fields.s = 1; /* code or data, i.e. not system */
- arbytes.fields.dpl = 0; /* DPL = 3 */
- arbytes.fields.p = 1; /* segment present */
- arbytes.fields.default_ops_size = 1; /* 32-bit */
- arbytes.fields.g = 1;
- arbytes.fields.null_bit = 0; /* not null */
- __vmwrite(GUEST_ES_AR_BYTES, arbytes.bytes);
- __vmwrite(GUEST_SS_AR_BYTES, arbytes.bytes);
- __vmwrite(GUEST_DS_AR_BYTES, arbytes.bytes);
- __vmwrite(GUEST_FS_AR_BYTES, arbytes.bytes);
- __vmwrite(GUEST_GS_AR_BYTES, arbytes.bytes);
- arbytes.fields.seg_type = 0xb; /* type = 0xb */
- __vmwrite(GUEST_CS_AR_BYTES, arbytes.bytes);
+ __vmwrite(GUEST_ES_AR_BYTES, 0xc093); /* read/write, accessed */
+ __vmwrite(GUEST_SS_AR_BYTES, 0xc093);
+ __vmwrite(GUEST_DS_AR_BYTES, 0xc093);
+ __vmwrite(GUEST_FS_AR_BYTES, 0xc093);
+ __vmwrite(GUEST_GS_AR_BYTES, 0xc093);
+ __vmwrite(GUEST_CS_AR_BYTES, 0xc09b); /* exec/read, accessed */
+
+ /* Guest IDT. */
+ __vmwrite(GUEST_IDTR_BASE, 0);
+ __vmwrite(GUEST_IDTR_LIMIT, 0);
/* Guest GDT. */
__vmwrite(GUEST_GDTR_BASE, 0);
__vmwrite(GUEST_GDTR_LIMIT, 0);
- /* Guest IDT. */
- __vmwrite(GUEST_IDTR_BASE, 0);
- __vmwrite(GUEST_IDTR_LIMIT, 0);
+ /* Guest LDT. */
+ __vmwrite(GUEST_LDTR_AR_BYTES, 0x0082); /* LDT */
+ __vmwrite(GUEST_LDTR_SELECTOR, 0);
+ __vmwrite(GUEST_LDTR_BASE, 0);
+ __vmwrite(GUEST_LDTR_LIMIT, 0);
- /* Guest LDT and TSS. */
- arbytes.fields.s = 0; /* not code or data segement */
- arbytes.fields.seg_type = 0x2; /* LTD */
- arbytes.fields.default_ops_size = 0; /* 16-bit */
- arbytes.fields.g = 0;
- __vmwrite(GUEST_LDTR_AR_BYTES, arbytes.bytes);
- arbytes.fields.seg_type = 0xb; /* 32-bit TSS (busy) */
- __vmwrite(GUEST_TR_AR_BYTES, arbytes.bytes);
+ /* Guest TSS. */
+ __vmwrite(GUEST_TR_AR_BYTES, 0x008b); /* 32-bit TSS (busy) */
+ __vmwrite(GUEST_TR_BASE, 0);
+ __vmwrite(GUEST_TR_LIMIT, 0xff);
__vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
__vmwrite(GUEST_DR7, 0);
__vmwrite(TPR_THRESHOLD, 0);
}
- __vmwrite(GUEST_LDTR_SELECTOR, 0);
- __vmwrite(GUEST_LDTR_BASE, 0);
- __vmwrite(GUEST_LDTR_LIMIT, 0);
-
- __vmwrite(GUEST_TR_BASE, 0);
- __vmwrite(GUEST_TR_LIMIT, 0xff);
-
vmx_vmcs_exit(v);
paging_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */